home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / Python1.4_Source / Lib / codehack.py < prev    next >
Text File  |  1998-06-24  |  2KB  |  68 lines

  1. # A subroutine for extracting a function name from a code object
  2. # (with cache)
  3.  
  4. import sys
  5. from stat import *
  6. import string
  7. import os
  8. import linecache
  9.  
  10. # XXX The functions getcodename() and getfuncname() are now obsolete
  11. # XXX as code and function objects now have a name attribute --
  12. # XXX co.co_name and f.func_name.
  13.  
  14. # Extract the function or class name from a code object.
  15. # This is a bit of a hack, since a code object doesn't contain
  16. # the name directly.  So what do we do:
  17. # - get the filename (which *is* in the code object)
  18. # - look in the code string to find the first SET_LINENO instruction
  19. #   (this must be the first instruction)
  20. # - get the line from the file
  21. # - if the line starts with 'class' or 'def' (after possible whitespace),
  22. #   extract the following identifier
  23. #
  24. # This breaks apart when the function was read from <stdin>
  25. # or constructed by exec(), when the file is not accessible,
  26. # and also when the file has been modified or when a line is
  27. # continued with a backslash before the function or class name.
  28. #
  29. # Because this is a pretty expensive hack, a cache is kept.
  30.  
  31. SET_LINENO = 127 # The opcode (see "opcode.h" in the Python source)
  32. identchars = string.letters + string.digits + '_' # Identifier characters
  33.  
  34. _namecache = {} # The cache
  35.  
  36. def getcodename(co):
  37.     key = `co` # arbitrary but uniquely identifying string
  38.     if _namecache.has_key(key): return _namecache[key]
  39.     filename = co.co_filename
  40.     code = co.co_code
  41.     name = ''
  42.     if ord(code[0]) == SET_LINENO:
  43.         lineno = ord(code[1]) | ord(code[2]) << 8
  44.         line = linecache.getline(filename, lineno)
  45.         words = string.split(line)
  46.         if len(words) >= 2 and words[0] in ('def', 'class'):
  47.             name = words[1]
  48.             for i in range(len(name)):
  49.                 if name[i] not in identchars:
  50.                     name = name[:i]
  51.                     break
  52.     _namecache[key] = name
  53.     return name
  54.  
  55. # Use the above routine to find a function's name.
  56.  
  57. def getfuncname(func):
  58.     return getcodename(func.func_code)
  59.  
  60. # A part of the above code to extract just the line number from a code object.
  61.  
  62. def getlineno(co):
  63.     code = co.co_code
  64.     if ord(code[0]) == SET_LINENO:
  65.         return ord(code[1]) | ord(code[2]) << 8
  66.     else:
  67.         return -1
  68.